#ifndef _UNI_TRANSP_TASK_HPP
#define _UNI_TRANSP_TASK_HPP

#include <graph\Graph.hpp>
#include <graph\Scheduler.hpp>

#include <GA\Task\Task.hpp>
#include <vector>
using std::vector;

namespace unitraf
{

  using unitraf::Scheduler;
  using unitraf::graph_traits::Graph;

  using unitraf::graph_traits::incidence_list_tag;
  using unitraf::graph_traits::directed_tag;
  using unitraf::graph_traits::no_property_tag;

class UniTranspTask
	: public Task
{
public:
	struct RouteDesc;
	class Fit;

  typedef unitraf::graph_traits::BusStopProperty bust_stop_property;
  typedef unitraf::graph_traits::StreetSectionProperty street_section_property;

  typedef Graph< 
    bust_stop_property,
    street_section_property,
    incidence_list_tag,
    directed_tag> graph_type;

  typedef Scheduler<graph_type> scheduler_type;

	//CONSTRUCTORS
	UniTranspTask( size_t routeNBits, size_t routeSizeBits, size_t routesSize, size_t routeMaxN , size_t busesMax);

	virtual void makeValid( BinaryString *BS ) const;
	virtual double fitness( BinaryString *BS, vector<Fit> * routes_values ) const;
  double fitness( BinaryString *BS) const { return fitness( BS, 0 ); };
		
	//protected:
	void encode( BinaryString *BS, vector<RouteDesc> &routes) const;
	void decode( BinaryString *BS, vector<RouteDesc> &routes) const;
		
	size_t routeBits( ) const { return _routeNBits + _routeSizeBits; }
	size_t routeSizeBits( ) const { return _routeSizeBits; }
	size_t routeNBits( ) const { return _routeNBits; }
	size_t routesSize( ) const { return _routesSize; }
	size_t routeMaxN( ) const { return _routeMaxN; }
	size_t busesMax( ) const { return _busesMax; }

private:
	size_t _routeNBits;
	size_t _routeSizeBits;
	size_t _routesSize;
	size_t _routeMaxN;
	size_t _busesMax;

  scheduler_type _scheduler;

  graph_type _graph;


};


struct UniTranspTask::RouteDesc
{
	size_t _n; //number of possible 
	size_t _size; //buses for this route 
};

class UniTranspTask::Fit
{
public:
	Fit( size_t n, double fit )
		: _n ( n ), _fit( fit ) { }
	size_t n( ) const { return _n; }
	double fit( ) const { return _fit; }
	bool operator< ( const Fit &other ) const { return fit( ) < other.fit( ); }
protected:
	size_t _n;
	double _fit;
};

}

#endif //#ifndef _UNI_TRANSP_TASK_HPP


